/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uloha4.main;

import java.util.ArrayList;
import java.util.LinkedList;
import uloha4.entities.Component;
import uloha4.entities.ComponentList;
import uloha4.entities.Node;

/**
 *
 * @author Tomique
 */
public class GraphToolkit {

    /**
     * Stavy jednotlivych uzlu pri prohledavani do hloubky
     */
    private enum State {

        FRESH, OPEN, CLOSE;
    }
    private static State[] states;

    /**
     * Vrati pseudonahodne cislo v zadanem intervalu
     *
     * @param lower
     * @param upper
     * @return
     */

    public static ComponentList getComponents(ArrayList<Node> graph) {

        // vysledne uloziste
        ComponentList list = ComponentList.getInstance();

        // vsechny uzly nejprve oznacim jako fresh
        states = new State[graph.size()];
        for (int i = 0; i < states.length; i++) {
            states[i] = State.FRESH;

        }

        for (Node node : graph) {
            // pokud je podminka splnena, prohledavam dale
            if (states[node.getId()] == State.FRESH) {
                Component<Node> comp = new Component<>();
                dfs(node, comp);
//                if (comp.size() > 25 && comp.size() < 30) {
                    list.add(comp);
//                    return list;
//                }
            }
        }
        return list;
    }

    private static void dfs(Node first, Component<Node> comp) {

        LinkedList<Node> stack = new LinkedList<>();
        states[first.getId()] = State.OPEN;
        stack.push(first);
        comp.add(first);

        while (!stack.isEmpty()) {

            Node node = stack.pop();

            ArrayList<Node> neighbours = node.getNeighbours();
            for (Node child : neighbours) {
                if (states[child.getId()] == State.FRESH) {
                    states[child.getId()] = State.OPEN;
                    stack.push(child);
                    comp.add(child);
                }
            }
            states[node.getId()] = State.CLOSE;
        }
    }
}
